package org.openfantasia.musica.instruments.jmusic;

import jm.audio.AudioObject;
import jm.audio.io.SampleOut;
import jm.audio.synth.*;

/**
 * A basic layered synthesis instrument
 *
 * @author Andrew Brown after Andrew Sorensen
 */

public final class BreathyFluteInst extends jm.audio.Instrument {

	//----------------------------------------------

	// Attributes

	//----------------------------------------------

	/**
	 * The points to use in the construction of Envelopes
	 */

	private EnvPoint[] pointArray = new EnvPoint[10];

	/**
	 * The points to use in the construction of Envelopes
	 */

	private EnvPoint[] pointArray2 = new EnvPoint[10];

	/**
	 * The number of channels
	 */

	private int channels;

	/**
	 * the sample rate passed to the instrument
	 */

	private int sampleRate;

	//----------------------------------------------

	// Constructor

	//----------------------------------------------


	/**
	 * Basic default constructor to set an initial
	 * <p/>
	 * sampling rate.
	 *
	 * @param sampleRate
	 */

	public BreathyFluteInst(int sampleRate) {

		this(sampleRate, 1);

	}


	/**
	 * A constructor to set an initial
	 * <p/>
	 * sampling rate and number of channels.
	 *
	 * @param sampleRate
	 */

	public BreathyFluteInst(int sampleRate, int channels) {

		this.sampleRate = sampleRate;

		this.channels = channels;

		// tone env

		EnvPoint[] tempArray = {

				new EnvPoint((float) 0.0, (float) 0.0),

				new EnvPoint((float) 0.2, (float) 1.0),

				new EnvPoint((float) 0.5, (float) 0.7),

				new EnvPoint((float) 0.8, (float) 0.5),

				new EnvPoint((float) 1.0, (float) 0.0)

		};

		pointArray = tempArray;

		// Noise env

		EnvPoint[] tempArray2 = {

				new EnvPoint((float) 0.0, (float) 0.0),

				new EnvPoint((float) 0.05, (float) 0.7),

				new EnvPoint((float) 0.2, (float) 0.1),

				new EnvPoint((float) 1.0, (float) 0.0)

		};

		pointArray2 = tempArray2;

	}

	//----------------------------------------------

	// Methods 

	//----------------------------------------------


	/**
	 * Initialisation method used to build the objects that
	 * <p/>
	 * this instrument will use
	 */

	public void createChain() {

		// main tone

		Oscillator wt = new Oscillator(this, Oscillator.SINE_WAVE, this.sampleRate, channels);

		Volume vol = new Volume(wt, (float) 1.0);

		// overtone

		Oscillator wt2 = new Oscillator(this, Oscillator.SINE_WAVE, this.sampleRate, channels);

		wt2.setFrqRatio((float) 2.001);

		Volume vol2 = new Volume(wt2, (float) 0.5);

		// overtone

		Oscillator wt3 = new Oscillator(this, Oscillator.SINE_WAVE, this.sampleRate, channels);

		wt3.setFrqRatio((float) 4.0);

		Volume vol3 = new Volume(wt3, (float) 0.1);

		// breath

		Noise noise = new Noise(this, Noise.WHITE_NOISE, this.sampleRate);

		Volume vol4 = new Volume(noise, (float) 0.2);

		// all together now

		AudioObject[] parts = {vol, vol2, vol3, vol4};

		Add add = new Add(parts);

		Envelope env = new Envelope(add, pointArray);

		StereoPan span = new StereoPan(env);

		SampleOut sout = new SampleOut(span);

	}

}

